module timeout_timer #(
    parameter integer NCNT = 1000
) (
    input  sys_clk,
    input  rst_n,
    input  timer_en_i,
    input  ref_pulse_i,
    input  check_pulse_i,
    output timeout_o
);

  localparam integer Width = $clog2(NCNT);

  wire almost_ovflw;
  reg [Width-1:0] cnt_reg;
  reg r_timeout;

  assign almost_ovflw = (cnt_reg == NCNT - 1);

  always @(posedge sys_clk, negedge rst_n) begin
    if (~rst_n) begin
      cnt_reg <= 0;
    end else if (check_pulse_i | timer_en_i) begin
      cnt_reg <= 0;
    end else if (ref_pulse_i) begin
      if (almost_ovflw) begin
        cnt_reg <= 0;
      end else begin
        cnt_reg <= cnt_reg + 1'b1;
      end
    end
  end

  always @(posedge sys_clk, negedge rst_n) begin
    if (~rst_n) begin
      r_timeout <= 1'b0;
    end else if (ref_pulse_i & almost_ovflw) begin
      r_timeout <= 1'b1;
    end else begin
      r_timeout <= 1'b0;
    end
  end

  assign timeout_o = r_timeout;

endmodule
